﻿namespace CommonData.Data.Core
{
    using CommonData.Data.Core.SQLCore;
    using CommonData.Entity;
    using CommonData.Util.Data;
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.SqlClient;

    public class BaseHelper : IBaseHelper, IDisposable
    {
        private IDbFactory factory = null;

        public T ConvertToEntity<T>(IDataReader reader) where T: class
        {
            T local = default(T);
            object obj2 = this.ConvertToEntity(typeof(T), reader);
            if (obj2 != null)
            {
                local = (T) obj2;
            }
            return local;
        }

        public object ConvertToEntity(Type type, IDataReader reader)
        {
            object obj2 = null;
            if (reader.Read())
            {
                obj2 = EntityFactory.CreateInstance(type, new object[0]);
                foreach (string str in EntityTypeCache.GetTableInfo(type).DicColumns.Keys)
                {
                    EntityTypeCache.GetTableInfo(type).DicProperties[str].SetValue(obj2, reader[str], null);
                }
                if (EntityTypeCache.GetTableInfo(type).DicLinkTable.Keys.Count <= 0)
                {
                    return obj2;
                }
                foreach (string str in EntityTypeCache.GetTableInfo(type).DicLinkTable.Keys)
                {
                    Type dataType = EntityTypeCache.GetTableInfo(type).DicLinkTable[str].DataType;
                    string sqlString = this.Factory.CreateSingleSql(dataType);
                    IDataParameter[] param = new IDataParameter[] { new SqlParameter() };
                    param[0].ParameterName = "@" + EntityTypeCache.GetTableInfo(EntityTypeCache.GetTableInfo(type).DicLinkTable[str].DataType).Table.PrimaryKeyName;
                    param[0].Value = EntityFactory.GetPropertyValue(obj2, EntityTypeCache.GetTableInfo(type).DicLinkTable[str].KeyName);
                    using (IDbProvider provider = new SqlProvider())
                    {
                        IDataReader reader2 = this.ExecuteDataReader(provider, sqlString, param);
                        object obj3 = EntityFactory.CreateInstance(dataType, false);
                        if (reader2.Read())
                        {
                            foreach (string str3 in EntityTypeCache.GetTableInfo(dataType).DicProperties.Keys)
                            {
                                EntityTypeCache.GetTableInfo(dataType).DicProperties[str3].SetValue(obj3, reader2[EntityTypeCache.GetTableInfo(dataType).DicColumns[str3].Name], null);
                            }
                        }
                        EntityTypeCache.GetTableInfo(type).DicProperties[str].SetValue(obj2, obj3, null);
                    }
                }
            }
            return obj2;
        }

        public IList<T> ConvertToList<T>(IDataReader reader) where T: class
        {
            T local = default(T);
            IList<T> list = new List<T>();
            while (reader.Read())
            {
                local = EntityFactory.CreateInstance<T>();
                foreach (string str in EntityTypeCache.GetTableInfo(typeof(T)).DicColumns.Keys)
                {
                    EntityTypeCache.GetTableInfo(typeof(T)).DicProperties[str].SetValue(local, reader[str], null);
                }
                if (EntityTypeCache.GetTableInfo(typeof(T)).DicLinkTable.Keys.Count > 0)
                {
                    foreach (string str in EntityTypeCache.GetTableInfo(typeof(T)).DicLinkTable.Keys)
                    {
                        Type dataType = EntityTypeCache.GetTableInfo(typeof(T)).DicLinkTable[str].DataType;
                        string sqlString = this.Factory.CreateSingleSql(dataType);
                        IDataParameter[] param = new IDataParameter[] { new SqlParameter() };
                        param[0].ParameterName = "@" + EntityTypeCache.GetTableInfo(EntityTypeCache.GetTableInfo(typeof(T)).DicLinkTable[str].DataType).Table.PrimaryKeyName;
                        param[0].Value = EntityFactory.GetPropertyValue(local, EntityTypeCache.GetTableInfo(typeof(T)).DicLinkTable[str].KeyName);
                        using (IDbProvider provider = new SqlProvider())
                        {
                            IDataReader reader2 = this.ExecuteDataReader(provider, sqlString, param);
                            object obj2 = EntityFactory.CreateInstance(dataType, false);
                            if (reader2.Read())
                            {
                                foreach (string str3 in EntityTypeCache.GetTableInfo(dataType).DicProperties.Keys)
                                {
                                    EntityTypeCache.GetTableInfo(dataType).DicProperties[str3].SetValue(obj2, reader2[EntityTypeCache.GetTableInfo(dataType).DicColumns[str3].Name], null);
                                }
                            }
                            EntityTypeCache.GetTableInfo(typeof(T)).DicProperties[str].SetValue(local, obj2, null);
                        }
                    }
                }
                list.Add(local);
            }
            return list;
        }

        public void Dispose()
        {
            throw new NotImplementedException();
        }

        public IDataReader ExecuteDataReader(IDbProvider provider, string sqlString)
        {
            return this.ExecuteDataReader(provider, sqlString, false, null);
        }

        public IDataReader ExecuteDataReader(IDbProvider provider, string sqlString, params IDataParameter[] param)
        {
            return this.ExecuteDataReader(provider, sqlString, false, param);
        }

        public IDataReader ExecuteDataReader(IDbProvider provider, string sqlString, bool isProcedure)
        {
            return this.ExecuteDataReader(provider, sqlString, isProcedure, null);
        }

        public IDataReader ExecuteDataReader(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param)
        {
            provider.Connection.Open();
            provider.Command.CommandText = sqlString;
            if (isProcedure)
            {
                provider.Command.CommandType = CommandType.StoredProcedure;
            }
            else
            {
                provider.Command.CommandType = CommandType.Text;
            }
            provider.Command.Parameters.Clear();
            provider.Command.Parameters.AddRange(param);
            return provider.Command.ExecuteReader();
        }

        public int ExecuteNonQuery(IDbProvider provider, string sqlString)
        {
            return this.ExecuteNonQuery(provider, sqlString, false, null);
        }

        public int ExecuteNonQuery(IDbProvider provider, string sqlString, params IDataParameter[] param)
        {
            return this.ExecuteNonQuery(provider, sqlString, false, param);
        }

        public int ExecuteNonQuery(IDbProvider provider, string sqlString, bool isProcedure)
        {
            return this.ExecuteNonQuery(provider, sqlString, isProcedure, null);
        }

        public int ExecuteNonQuery(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param)
        {
            provider.Connection.Open();
            provider.Command.CommandText = sqlString;
            if (isProcedure)
            {
                provider.Command.CommandType = CommandType.StoredProcedure;
            }
            else
            {
                provider.Command.CommandType = CommandType.Text;
            }
            provider.Command.Parameters.Clear();
            provider.Command.Parameters.AddRange(param);
            return provider.Command.ExecuteNonQuery();
        }

        public object ExecuteScalar(IDbProvider provider, string sqlString)
        {
            return this.ExecuteScalar(provider, sqlString, false, null);
        }

        public object ExecuteScalar(IDbProvider provider, string sqlString, bool isProcedure)
        {
            return this.ExecuteScalar(provider, sqlString, isProcedure, null);
        }

        public object ExecuteScalar(IDbProvider provider, string sqlString, params IDataParameter[] param)
        {
            return this.ExecuteScalar(provider, sqlString, false, param);
        }

        public object ExecuteScalar(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param)
        {
            provider.Connection.Open();
            provider.Command.CommandText = sqlString;
            if (isProcedure)
            {
                provider.Command.CommandType = CommandType.StoredProcedure;
            }
            else
            {
                provider.Command.CommandType = CommandType.Text;
            }
            provider.Command.Parameters.Clear();
            provider.Command.Parameters.AddRange(param);
            return provider.Command.ExecuteScalar();
        }

        public DataTable ExecuteTable(IDbProvider provider, string sqlString)
        {
            return this.ExecuteTable(provider, sqlString, false, null);
        }

        public DataTable ExecuteTable(IDbProvider provider, string sqlString, bool isProcedure)
        {
            return this.ExecuteTable(provider, sqlString, isProcedure, null);
        }

        public DataTable ExecuteTable(IDbProvider provider, string sqlString, params IDataParameter[] param)
        {
            return this.ExecuteTable(provider, sqlString, false, param);
        }

        public DataTable ExecuteTable(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param)
        {
            provider.Connection.Open();
            provider.Command.CommandText = sqlString;
            if (isProcedure)
            {
                provider.Command.CommandType = CommandType.StoredProcedure;
            }
            else
            {
                provider.Command.CommandType = CommandType.Text;
            }
            provider.Command.Parameters.Clear();
            provider.Command.Parameters.AddRange(param);
            DataSet dataSet = new DataSet();
            provider.Adapter.Fill(dataSet);
            return dataSet.Tables[0];
        }

        public IDbFactory Factory
        {
            get
            {
                if (this.factory == null)
                {
                    this.factory = new SqlFactory();
                }
                return this.factory;
            }
            set
            {
                this.factory = value;
            }
        }
    }
}

